#coding=utf-8
import sys

from uliweb.orm import get_model, set_dispatch_send, Begin, Commit, Rollback, do_

set_dispatch_send(False)

log = open('log.txt', 'w')

def call(args, options, global_options):
    from uliweb.core.SimpleFrame import get_apps, get_app_dir, Dispatcher

    app = Dispatcher(apps_dir=global_options.apps_dir, start=False)
    try:
        Begin()
        try:
            process(args, options, global_options)
            Commit()
        except:
            Rollback()
            import traceback
            traceback.print_exc()
    finally:
        log.close()
        
mapping = {
    'B':('0060', 'B'),
    'E':('0060', 'E'),
    'S':('1030', 'M'),
    'R':('1010', 'M'),
    'D':('1020', 'M'),
    'U':('0070', 'B'),
    'u':('0070', 'E'),
    'T':('0080', 'B'),
    't':('0080', 'E'),
    'F':('0090', 'B'),
    'f':('0090', 'E'),
    'N':('0100', 'B'),
    'n':('0100', 'E')
}

m_fields = {
    'test_beginDate':('0060', 'B'),
    'test_endDate':('0060', 'E'),
    'version_date':('1030', 'M'),
    'req_close_date':('1010', 'M'),
    'design_close_date':('1020', 'M'),
    'uat_begin_date':('0070', 'B'),
    'uat_end_date':('0070', 'E'),
    'tune_begin_date':('0080', 'B'),
    'tune_end_date':('0080', 'E'),
    'func_inst_begin_date':('0090', 'B'),
    'func_inst_end_date':('0090', 'E'),
    'tune_inst_begin_date':('0100', 'B'),
    'tune_inst_end_date':('0100', 'E'),
}

#test_beginDate = Field(datetime.date, verbose_name='集成测试开始时间')
#test_endDate = Field(datetime.date, verbose_name='集成测试结束时间')
#version_date = Field(datetime.date, verbose_name='投产时间')
##其它里程碑点
#req_close_date = Field(datetime.date, verbose_name='需求封版时间')
#design_close_date = Field(datetime.date, verbose_name='设计封版时间')
#uat_begin_date = Field(datetime.date, verbose_name='UAT测试开始时间')
#uat_end_date = Field(datetime.date, verbose_name='UAT测试结束时间')
#tune_begin_date = Field(datetime.date, verbose_name='性能调优开始时间')
#tune_end_date = Field(datetime.date, verbose_name='性能调优结束时间')
#func_inst_begin_date = Field(datetime.date, verbose_name='功能版本安装测试开始时间')
#func_inst_end_date = Field(datetime.date, verbose_name='功能版本安装测试结束时间')
#tune_inst_begin_date = Field(datetime.date, verbose_name='非功能版本安装测试开始时间')
#tune_inst_end_date = Field(datetime.date, verbose_name='非功能版本安装测试结束时间')

#{'stage':'02', 'type':'2', 'title':'需求封版时间', 'idn':'1010', 'must':True},
#{'stage':'02', 'type':'1', 'test_type':False, 'title':'需求分析', 'idn':'0010', 'must':False},
#{'stage':'03', 'type':'2', 'title':'设计封版时间', 'idn':'1020', 'must':True},     
#{'stage':'03', 'type':'1', 'test_type':False, 'title':'概要设计', 'idn':'0020', 'must':False},
#{'stage':'04', 'type':'1', 'test_type':False, 'title':'详细设计', 'idn':'0030', 'must':False},
#{'stage':'05', 'type':'1', 'test_type':False, 'title':'开发', 'idn':'0040', 'must':False},
#{'stage':'06', 'type':'1', 'test_type':False, 'title':'内部测试', 'idn':'0050', 'must':False},
#{'stage':'07', 'type':'1', 'test_type':True, 'title':'集成测试', 'idn':'0060', 'must':False},
#{'stage':'08', 'type':'1', 'test_type':True, 'title':'用户测试', 'idn':'0070', 'must':False},
#{'stage':'09', 'type':'1', 'test_type':True, 'title':'非功能测试', 'idn':'0080', 'must':False},
#{'stage':'10', 'type':'1', 'test_type':True, 'title':'版本功能验证测试', 'idn':'0090', 'must':False},
#{'stage':'10', 'type':'1', 'test_type':True, 'title':'版本非功能验证测试', 'idn':'0100', 'must':False},
#{'stage':'11', 'type':'1', 'test_type':False, 'title':'投产', 'idn':'0110', 'must':True},
#{'stage':'11', 'type':'2', 'title':'投产时间', 'idn':'1030', 'must':True, 'weight':1},    

def get_plan_def(idn):
    from uliweb import settings
    
    for x in settings.get_var('PARA/PLAN_DEFS'):
        if idn == x['idn']:
            return x
        
def process(args, options, global_options):
    from sqlalchemy.sql import func
    from uliweb import settings
    
    M = get_model('milestone_plan')
    T = get_model('tasks_milestone')
    Plan = get_model('plan')
    PlanEdit = get_model('planedit')
    PlanExecute = get_model('planexecute')
    D = get_model('milestone_details')
    PlanChange = get_model('planchange')
    Task = get_model('tasks_develop')
    Plan.modified_date.auto_now = None
    Plan.modified_date.auto_now_add = None
    PlanExecute.modified_date.auto_now = None
    PlanExecute.modified_date.auto_now_add = None
    PlanChange.modified_date.auto_now = None
    PlanChange.modified_date.auto_now_add = None
    
    Plan.remove()
    do_(Plan.systems.table.delete())
    PlanEdit.remove()
    do_(PlanEdit.systems.table.delete())
    PlanExecute.remove()
    PlanChange.remove()
    
#    for t in T.all():
#        if M.count((M.c.task==t._task_) & (M.c.id==t._milestone_plan_)) == 0:
#            t.delete()
    
    plan_mapping = {}
    
    #处理milestone_plan表
    print "Process Milestone_Plan..."
    for m in M.all():
        if not m.plan_date:
            print >> log, "Info: no plan_date, skip task=[%d] milestone=[%d]" % (m._task_, m.id)
            continue
        x = mapping.get(m.flag)
        if not x:   #自定义里程碑
            print >> log, "Info: self milestone task=[%d] milestone=[%d]" % (m._task_, m.id)
            
            result = Plan.filter((Plan.c.task==m._task_) & (Plan.c.is_reserved==False)).values_one(func.max(Plan.c.idn))[0]
            if result:
                idn = str(int(result)+1).zfill(4)
            else:
                idn = '5001'
            
            row = Plan(task=m._task_, title=m.name, type='2', 
                end_date=m.plan_date, test_type=False, memo=m.memo,
                idn=idn, main_sys=m.task._task_sys_, is_public=True, is_reserved=False,
                stage='05', weight=0,
                modified_date=m.modified_date, modified_user=m._modified_user_)
            row.save()
            ids = m.task.requirement.systems.ids()
            row.systems.add(ids)
#            row.systems.add(m.task._task_sys_)
            plan_mapping[m.id] = row.id
            
            pe = PlanExecute(task=m._task_, plan=row.id, type='2', system=m.task._task_sys_, 
                modified_date=m.modified_date, modified_user=m._modified_user_)
            pe.save()
            
            #保存子任务
            for t in m.task.child_tasks.all():
                pe = PlanExecute(task=t.id, plan=row.id, type=type, system=t._task_sys_, 
                    modified_date=m.modified_date, modified_user=m._modified_user_)
                pe.save()
            
            continue
        row = Plan.get((Plan.c.task==m._task_) & (Plan.c.idn==x[0]))
        if row:
            if x[1] == 'M':
                #说明有重复的，打印出来
                print >> log, "duplicated...", row.id, m.id, m._task_, x[0]
            elif x[1] == 'B':
                row.begin_date = m.plan_date
                row.save()
            else:
                row.end_date = m.plan_date
                row.save()
            
            plan_mapping[m.id] = row.id
            print >> log, "Info: %d--%d" % (m.id, row.id)
            
        else:
            if x[1] == 'M':
                type = '2'
                begin_date = None
                end_date = m.plan_date
            else:
                type = '1'
                if x[1] == 'B':
                    begin_date = m.plan_date
                    end_date = None
                else:
                    begin_date = None
                    end_date = m.plan_date
            plan_def = get_plan_def(x[0])
            task = Task.get(m._task_)
            if not task:
                print >> log, "Warn: Task [%d] has already been deleted" % m._task_
                continue
            row = Plan(task=m._task_, title=plan_def['title'], type=type, begin_date=begin_date,
                end_date=end_date, test_type=plan_def.get('test_type', False), memo=m.memo,
                idn=x[0], main_sys=m.task._task_sys_, is_public=True, is_reserved=True,
                stage=plan_def['stage'], weight=plan_def.get('weight', 0),
                modified_date=m.modified_date, modified_user=m._modified_user_)
            row.save()
            ids = m.task.requirement.systems.ids()
            row.systems.add(ids)
            
            #保存plan_id和milestone_id的对照
            plan_mapping[m.id] = row.id
            print >> log, "Info: %d--%d" % (m.id, row.id)
            
            #保存主任务
            pe = PlanExecute(task=m._task_, plan=row.id, type=type, system=m.task._task_sys_, 
                modified_date=m.modified_date, modified_user=m._modified_user_)
            pe.save()
            
            #保存子任务
            for t in m.task.child_tasks.all():
                pe = PlanExecute(task=t.id, plan=row.id, type=type, system=t._task_sys_, 
                    modified_date=m.modified_date, modified_user=m._modified_user_)
                pe.save()
        
    #处理PlanEdit
    print "Process Task & PlanEdit..."
    for t in Task.filter(Task.c.version_headerId==None):
        for k, v in m_fields.items():
            if v[1] == 'M':
                type = '2'
                f = 'end_date'
                begin_date = None
                end_date = getattr(t, k)
            else:
                type = '1'
                if v[1] == 'B':
                    f = 'begin_date'
                    begin_date = getattr(t, k)
                    end_date = None
                else:
                    f = 'end_date'
                    begin_date = None
                    end_date = getattr(t, k)
            if getattr(t, k):
                plan = Plan.get((Plan.c.idn==v[0]) & (Plan.c.task==t.id))
                if plan:
                    if not getattr(plan, f):
                        setattr(plan, f, getattr(t, k))
                        plan.save()
                else:
                    plan_def = get_plan_def(v[0])
                    row = Plan(task=t.id, title=plan_def['title'], type=type, begin_date=begin_date,
                        end_date=end_date, test_type=plan_def.get('test_type', False), memo='',
                        idn=v[0], main_sys=t._task_sys_, is_public=True, is_reserved=True,
                        stage=plan_def['stage'], weight=plan_def.get('weight', 0),
                        modified_date=t.modified_date, modified_user=t._modified_user_)
                    row.save()
                    ids = t.requirement.systems.ids()
                    row.systems.add(ids)
                    
        #创建结束时间Plan
        plan_def = get_plan_def('1090')
        row = Plan(task=t.id, title=plan_def['title'], type='2', 
            end_date=t.end_time, test_type=plan_def.get('test_type', False), memo='',
            idn='1090', main_sys=t._task_sys_, is_public=True, is_reserved=True,
            stage=plan_def['stage'], weight=plan_def.get('weight', 0),
            modified_date=t.modified_date, modified_user=t._modified_user_)
        row.save()
        ids = t.requirement.systems.ids()
        row.systems.add(ids)
        
        #处理任务完成
        if t.stage == 'FN':
            e = PlanExecute(task=row._task_, plan=row.id, system=row.task._task_sys_, 
                type=row.type, finish_end_date=t.end_time, modified_date=t.modified_date, 
                modified_user=t._modified_user_)
            e.save()
            
            #保存子任务
            for x in row.task.child_tasks.all():
                if row.systems.has(t.task_sys):
                    pe = PlanExecute(task=x.id, plan=row.id, type=row.type, 
                        system=x._task_sys_, finish_end_date=x.end_time, modified_date=x.modified_date, 
                        modified_user=x._modified_user_)
                    pe.save()
        else:
            e = PlanExecute(task=row._task_, plan=row.id, system=row.task._task_sys_, 
                type=row.type, modified_date=t.modified_date, modified_user=t._modified_user_)
            e.save()
            
            #保存子任务
            for x in row.task.child_tasks.all():
                if row.systems.has(t.task_sys):
                    pe = PlanExecute(task=x.id, plan=row.id, type=row.type, 
                        system=x._task_sys_, modified_date=x.modified_date, 
                        modified_user=x._modified_user_)
                    pe.save()
                    
        for p in settings.get_var('PARA/PLAN_DEFS'):
            pe = PlanEdit(task=t.id, title=p['title'], type=p['type'], test_type=p.get('test_type', False),
                idn=p['idn'], is_public=True, is_reserved=True, main_sys=task._task_sys_, stage=p['stage'], 
                weight=p.get('weight', 0), enabled=False)
            pe.save()
#            ids = t.requirement.systems.ids()
#            pe.systems.add(ids)
        for x in Plan.filter(Plan.c.task==t.id):
            pe = PlanEdit.get((PlanEdit.c.task==t.id) & (PlanEdit.c.idn==x.idn))
            if pe:
                pe.begin_date = x.begin_date
                pe.end_date = x.end_date
                pe.enabled = True
                pe.memo = (pe.memo or '') + (x.memo or '')
                pe.save()
                ids = x.task.requirement.systems.ids()
                pe.systems.add(ids)
            else:
                #自定义里程碑
                pe = PlanEdit(task=x._task_, title=x.title, type=x.type, test_type=x.test_type,
                    idn=x.idn, is_public=x.is_public, is_reserved=x.is_reserved, main_sys=x._main_sys_, stage=x.stage, 
                    weight=x.weight, enabled=True, memo=x.memo)
                pe.save()
#                pe.systems.add(x._main_sys_)
                ids = t.requirement.systems.ids()
                pe.systems.add(ids)
            
    #处理tasks_milestone表
    print "Process Tasks_Milestone..."
    for t in T.all():
        task = Task.get(t._task_)
        if not task:
            print >> log, "Warn: Task [%d] has already been deleted" % t._task_
            continue
        if not plan_mapping.get(t._milestone_plan_):
            print >> log, "Error: Missing plan_id [%d] milestone-plan [%d]" % (t.id, t._milestone_plan_)
            continue
        pe = PlanExecute.get((PlanExecute.c.task==t._task_) &
            (PlanExecute.c.plan==plan_mapping[t._milestone_plan_]))
        if not pe:
            print >> log, "Error: Can't find the PlanExecute record task=[%d], old_plan=[%d], new_plan=[%d]" % (t._task_, t._milestone_plan_, plan_mapping[t._milestone_plan_])
            continue
        x = mapping.get(t.milestone_plan.flag)
        if not x:
            pe.finish_end_date = t.finish_date
        else:
            if x[1] == 'M':
                pe.finish_end_date = t.finish_date
            else:
                if x[1] == 'B':
                    pe.finish_begin_date = t.finish_date
                else:
                    pe.finish_end_date = t.finish_date
        if t.status not in ('1', '2'):
            t.status = '1'
        pe.status = pe.status or t.status
        if t.status != '1':
            pe.status = t.status
        pe.memo = (pe.memo or '') + (t.memo or '')
        pe.modified_date=t.modified_date
        pe.modified_user=t._modified_user_
        pe.save()
        
    #处理修改记录
    print "Process Milestone_Details..."
    for d in D.all():
        task = Task.get(d._task_)
        if not task:
            print >> log, "Warn: Task [%d] has already been deleted" % d._task_
            continue
        if not plan_mapping.get(d._milestone_plan_):
            print >> log, "Error: Missing plan_id [%d] milestone-plan [%d]" % (d.id, d._milestone_plan_)
            continue
        plan = Plan.get(plan_mapping[d._milestone_plan_])
        c = PlanChange(task_id=d._task_, plan_id=plan_mapping[d._milestone_plan_],
            modify_flag=d.modify_flag, old_value=d.old_value, 
            changed_value=d.changed_value, idn=plan.idn, weight=plan.weight,
            modified_date=d.modified_date, modified_user=d._modified_user_)
        c.save()